package com.example.my_helper;

import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.TypeEvaluator;
import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.Service;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.net.DhcpInfo;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.os.Handler;
import android.os.Message;
import android.os.Vibrator;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.style.ForegroundColorSpan;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.PopupWindow;
import android.widget.ScrollView;
import android.widget.Spinner;
import android.widget.Switch;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.RequiresApi;
import androidx.core.app.NotificationCompat;

import com.example.my_helper.modbus4j.ModbusLocator;
import com.example.my_helper.modbus4j.code.DataType;
import com.example.my_helper.mymqtt.MqttAndroidClient;

import org.eclipse.paho.client.mqttv3.IMqttActionListener;
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.IMqttToken;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;

import java.math.BigInteger;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;


public class MQTTDebuger {

    final static int ON_CONNECT = 0;
    final static int ON_MESSAGE = 1;
    final static int ON_SEND = 2;
    final static int ON_CLOSE = 3;
    final static int ON_ERROR = 4;
    final static int NOT_FOUND = 5;
    final static int NO_PERMISSION = 6;
    final static int CONFIG_ERROR = 7;
    final static int UNSUPPORT = 8;
    final static int CONSOLE_LOG = 9;
    final static int CONSOLE_REFRESH = 10;
    final static int SEND_DATA = 11;


    public MainActivity parent;
    public Handler handler;

    View mqtt_view;
    ListView message_list, subscribe_list;
    TextView status_label;
    EditText topic_input, message_input;
    Button subscribe_window_bt, setting_bt, send_bt, clear_bt;
    Spinner qos_spinner;
    Switch retained_switch;

    SpannableStringBuilder console_buf = new SpannableStringBuilder("");
    @SuppressLint("SimpleDateFormat")
    public SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");


    final boolean[] flag = {false};
    int config_layout_heigth, config_hiden_layout_heigth;
    public boolean console_pause = false;
    public boolean auto_send_flag = false;
    public int recv_count = 0;
    public int send_count = 0;
    static boolean send_input_flag = false;
    public boolean console_lock = false;
    static int send_input_len = 0;
    private Lock lock = new ReentrantLock();
    private Lock rw_lock = new ReentrantLock();
    ArrayList<SubscribeTopic> subscribeTopics;
    MyMQTTConnection myMQTTConnection;
    MqttAndroidClient mqttAndroidClient;
    ArrayList<MyMqttMessage> myMqttMessages = new ArrayList<>();
    MyMessageAdapter messageAdapter;

    @SuppressLint("ClickableViewAccessibility")
    public MQTTDebuger(MainActivity parent){
        this.parent = parent;
        this.mqtt_view = parent.mqtt_view;
        status_label = mqtt_view.findViewById(R.id.mqtt_status_label);
        subscribe_window_bt = mqtt_view.findViewById(R.id.mqtt_subscribe_window_bt);
        setting_bt = mqtt_view.findViewById(R.id.mqtt_setting_bt);
        subscribe_list = mqtt_view.findViewById(R.id.mqtt_subscribe_list);
        message_list = mqtt_view.findViewById(R.id.mqtt_message_list);
        topic_input = mqtt_view.findViewById(R.id.mqtt_topic_input);
        message_input = mqtt_view.findViewById(R.id.mqtt_message_input);
        qos_spinner = mqtt_view.findViewById(R.id.mqtt_qos_spinner);
        retained_switch = mqtt_view.findViewById(R.id.mqtt_retained_switch);
        clear_bt = mqtt_view.findViewById(R.id.mqtt_clear_bt);
        send_bt = mqtt_view.findViewById(R.id.mqtt_send_bt);

        messageAdapter = new MyMessageAdapter(myMqttMessages, parent);
        message_list.setAdapter(messageAdapter);

        subscribeTopics = MyApp.myDBHelper.subscribe_topic_getdata();
        myMQTTConnection = MyApp.myDBHelper.mqtt_setting_getdata();

        message_list.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
            @Override
            public boolean onItemLongClick(AdapterView<?> parent1, View view, int position, long id) {
                Vibrator vb = (Vibrator)parent.getSystemService(Service.VIBRATOR_SERVICE);
                vb.vibrate(50);
                ClipboardManager cm = (ClipboardManager) parent.getSystemService(Context.CLIPBOARD_SERVICE);
                ClipData mClipData = ClipData.newPlainText("Label", myMqttMessages.get(position).message);
                cm.setPrimaryClip(mClipData);
                Toast.makeText(parent, "已复制消息到剪贴板", Toast.LENGTH_SHORT).show();
                return true;
            }
        });

        subscribe_window_bt.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Show_subscribe_window(v);
            }
        });
        setting_bt.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Show_setting_window(v);
            }
        });

        send_bt.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(mqttAndroidClient != null && mqttAndroidClient.isConnected()){
                    if(topic_input.length() != 0) {
                        String s = message_input.getText().toString();
                        MqttMessage msg = new MqttMessage();
                        msg.setPayload(s.getBytes());
                        msg.setQos(qos_spinner.getSelectedItemPosition());
                        msg.setRetained(retained_switch.isChecked());
                        try {
                            mqttAndroidClient.publish(topic_input.getText().toString(), msg);
                        } catch (MqttException e) {
                            e.printStackTrace();
                            Toast.makeText(parent, "发送失败", Toast.LENGTH_SHORT).show();
                        }
                    }
                }else{
                    Toast.makeText(parent, "未连接", Toast.LENGTH_SHORT).show();
                }
            }
        });

        clear_bt.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                myMqttMessages.clear();
                messageAdapter.notifyDataSetChanged();
                MyMqttMessage.index = 0;
            }
        });

/*        handler = new Handler(msg -> {
            String s;
            switch(msg.what){
                case ON_CONNECT:
                    status_label.setText("状态：已连接");
                    break;
                case ON_MESSAGE:
                    break;
                case ON_SEND:
                    break;
                case ON_CLOSE:
                    break;
                case ON_ERROR:
                    break;
                default:
                    break;
            }
            return false;
        });*/

    }

    @SuppressLint("SetTextI18n")
    private void Show_setting_window(View v) {
        EditText host_input, port_input, username_input, password_input, client_id_input, keep_alive_input, will_topic_input, will_message_input;
        Switch clean_seasion_switch, will_retained_switch;
        View setting_view = LayoutInflater.from(parent).inflate(R.layout.mqtt_setting_window, null, false);
        Button setting_cancel_bt = setting_view.findViewById(R.id.setting_cancel_bt);
        Button setting_connect_bt = setting_view.findViewById(R.id.setting_connect_bt);
        host_input = setting_view.findViewById(R.id.mqtt_host_input);
        port_input = setting_view.findViewById(R.id.mqtt_port_input);
        username_input = setting_view.findViewById(R.id.mqtt_username_input);
        password_input = setting_view.findViewById(R.id.mqtt_password_input);
        client_id_input = setting_view.findViewById(R.id.mqtt_client_id_input);
        keep_alive_input = setting_view.findViewById(R.id.mqtt_keep_alive_input);
        will_topic_input = setting_view.findViewById(R.id.mqtt_will_topic_input);
        will_message_input = setting_view.findViewById(R.id.mqtt_will_message_input);
        clean_seasion_switch = setting_view.findViewById(R.id.mqtt_clean_seasion_switch);
        will_retained_switch = setting_view.findViewById(R.id.mqtt_will_retained_switch);
        Spinner will_qos = setting_view.findViewById(R.id.mqtt_will_qos_spinner);

        if(myMQTTConnection != null){
            host_input.setText(myMQTTConnection.host);
            port_input.setText(myMQTTConnection.port+"");
            username_input.setText(myMQTTConnection.username);
            password_input.setText(myMQTTConnection.password);
            client_id_input.setText(myMQTTConnection.client_id);
            keep_alive_input.setText(myMQTTConnection.keep_alive+"");
            clean_seasion_switch.setChecked(myMQTTConnection.clean_seasion);
            will_topic_input.setText(myMQTTConnection.last_will_topic);
            will_message_input.setText(myMQTTConnection.last_will_message);
            will_qos.setSelection(myMQTTConnection.last_will_qos);
            will_retained_switch.setChecked(myMQTTConnection.last_will_retained);
        }

        if(client_id_input.length() == 0){
            client_id_input.setText(MyMQTTConnection.generate_client_id());
        }

        //1.构造一个PopupWindow，参数依次是加载的View，宽高
        PopupWindow popWindow = new PopupWindow(setting_view, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, true);
        popWindow.setAnimationStyle(R.style.popupAnimation);  //设置加载动画
        popWindow.setTouchable(true);
        popWindow.setTouchInterceptor(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                return false;
            }
        });
        popWindow.setBackgroundDrawable(new ColorDrawable(0x00000000));    //要为popWindow设置一个背景才有效
        popWindow.setOnDismissListener(new PopupWindow.OnDismissListener() {
            @Override
            public void onDismiss() {
                WindowManager.LayoutParams lp = parent.getWindow().getAttributes();
                parent.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
                lp.alpha = 1f;
                parent.getWindow().setAttributes(lp);
            }
        });
        setting_cancel_bt.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                popWindow.dismiss();
            }
        });

        setting_connect_bt.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                try {
                    if(host_input.length() == 0)
                        throw new IllegalArgumentException("服务器地址不能为空");
                    if(host_input.length() == 0)
                        throw new IllegalArgumentException("服务器端口不能为空");
//                    if(client_id_input.length() == 0){
//                        myMQTTConnection = new MyMQTTConnection(host_input.getText().toString(), Integer.parseInt(port_input.getText().toString()));
//                    } else {
//                        myMQTTConnection = new MyMQTTConnection(host_input.getText().toString(), Integer.parseInt(port_input.getText().toString()), username_input.getText().toString(), password_input.getText().toString(), client_id_input.getText().toString());
//                    }
                    myMQTTConnection.host = host_input.getText().toString();
                    myMQTTConnection.port = Integer.parseInt(port_input.getText().toString());
                    myMQTTConnection.username = username_input.getText().toString();
                    myMQTTConnection.password = password_input.getText().toString();
                    if(client_id_input.length() > 0)
                        myMQTTConnection.client_id = client_id_input.getText().toString();
                    myMQTTConnection.keep_alive = Integer.parseInt(keep_alive_input.getText().toString());
                    myMQTTConnection.clean_seasion = clean_seasion_switch.isChecked();
                    myMQTTConnection.last_will_topic = will_topic_input.getText().toString();
                    myMQTTConnection.last_will_message = will_message_input.getText().toString();
                    myMQTTConnection.last_will_qos = will_qos.getSelectedItemPosition();
                    myMQTTConnection.last_will_retained = will_retained_switch.isChecked();
                    Connect(myMQTTConnection);
                    MyApp.myDBHelper.mqtt_setting_update(myMQTTConnection);
                    popWindow.dismiss();
                }catch(Exception e){
                    e.printStackTrace();
                    Toast.makeText(parent, e.getMessage(), Toast.LENGTH_SHORT).show();
                }

            }
        });
        //popWindow.showAsDropDown(serial_view, 50, 50);
        popWindow.showAtLocation(mqtt_view, Gravity.CENTER, 0, 0);
        WindowManager.LayoutParams lp = parent.getWindow().getAttributes();
        parent.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
        lp.alpha = 0.3f;
        parent.getWindow().setAttributes(lp);
    }

    @SuppressLint("ClickableViewAccessibility")
    private void Show_subscribe_window(View v) {
        View subscribe_view = LayoutInflater.from(parent).inflate(R.layout.mqtt_subscribe_window, null, false);
        ListView subscribe_list = subscribe_view.findViewById(R.id.mqtt_subscribe_list);
        Button subscribe_bt = subscribe_view.findViewById(R.id.mqtt_subscribe_bt);
        EditText subscribe_input = subscribe_view.findViewById(R.id.mqtt_subscribe_input);
        Spinner subscribe_qos = subscribe_view.findViewById(R.id.subscribe_qos_spinner);
        //1.构造一个PopupWindow，参数依次是加载的View，宽高
        PopupWindow popWindow = new PopupWindow(subscribe_view, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, true);
        popWindow.setAnimationStyle(R.style.popupAnimation);  //设置加载动画
        popWindow.setTouchable(true);
        popWindow.setTouchInterceptor(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                return false;
            }
        });
        popWindow.setBackgroundDrawable(new ColorDrawable(0x00000000));    //要为popWindow设置一个背景才有效
        popWindow.setOnDismissListener(new PopupWindow.OnDismissListener() {
            @Override
            public void onDismiss() {
                WindowManager.LayoutParams lp = parent.getWindow().getAttributes();
                parent.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
                lp.alpha = 1f;
                parent.getWindow().setAttributes(lp);
            }
        });

        SubscribeTopicAdapter adapter = new SubscribeTopicAdapter(subscribeTopics, parent);

        final float[] register_on_click_x = {0};
        subscribe_list.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                register_on_click_x[0] = event.getX();
                return false;
            }
        });

        subscribe_list.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
            @Override
            public boolean onItemLongClick(AdapterView<?> parent1, View view1, int position, long id) {
                View delete_view = LayoutInflater.from(parent).inflate(R.layout.kuaijie_delete_layout, null, false);
                Button delete_bt = (Button) delete_view.findViewById(R.id.kuaijie_delete_bt);
                //1.构造一个PopupWindow，参数依次是加载的View，宽高
                PopupWindow popWindow2 = new PopupWindow(delete_view, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, true);
                popWindow2.setTouchable(true);
                popWindow2.setTouchInterceptor(new View.OnTouchListener() {
                    @Override
                    public boolean onTouch(View v, MotionEvent event) {
                        return false;
                    }
                });
                popWindow2.setBackgroundDrawable(new ColorDrawable(0x00000000));
                popWindow2.showAsDropDown(view1, (int) register_on_click_x[0]-200, 0);
                delete_bt.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        try {
                            mqttAndroidClient.unsubscribe(subscribeTopics.get(position).topic);
                            MyApp.myDBHelper.subscribe_topic_delete(subscribeTopics.get(position).topic);
                            subscribeTopics.remove(position);
                            adapter.notifyDataSetChanged();
                        } catch (MqttException e) {
                            e.printStackTrace();
                            Toast.makeText(parent, "取消订阅失败", Toast.LENGTH_SHORT).show();
                        }
                        popWindow2.dismiss();
                    }
                });
                return true;
            }
        });

        subscribe_list.setAdapter(adapter);
        subscribe_bt.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(mqttAndroidClient == null || !mqttAndroidClient.isConnected()){
                    Toast.makeText(parent, "未连接", Toast.LENGTH_SHORT).show();
                    return;
                }
                String s = subscribe_input.getText().toString();
                if(s.length() > 0) {
                    boolean isExist = false;
                    for(SubscribeTopic topic : subscribeTopics){
                        if(topic.topic.equals(s)){
                            isExist = true;
                        }
                    }
                    if(!isExist) {
                        try {
                            mqttAndroidClient.subscribe(s, subscribe_qos.getSelectedItemPosition());
                            subscribeTopics.add(new SubscribeTopic(s, subscribe_qos.getSelectedItemPosition()));
                            MyApp.myDBHelper.subscribe_topic_insert(s, subscribe_qos.getSelectedItemPosition());
                            adapter.notifyDataSetChanged();
                            Toast.makeText(parent, "订阅成功", Toast.LENGTH_SHORT).show();
                        } catch (MqttException e) {
                            e.printStackTrace();
                            Toast.makeText(parent, "订阅失败", Toast.LENGTH_SHORT).show();
                        }

                    } else {
                        Toast.makeText(parent, "主题已存在", Toast.LENGTH_SHORT).show();
                    }
                } else
                    Toast.makeText(parent, "主题不能为空", Toast.LENGTH_SHORT).show();
            }
        });

        //popWindow.showAsDropDown(serial_view, 50, 50);
        popWindow.showAtLocation(mqtt_view, Gravity.CENTER, 0, 0);
        WindowManager.LayoutParams lp = parent.getWindow().getAttributes();
        parent.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
        lp.alpha = 0.3f;
        parent.getWindow().setAttributes(lp);
    }

    public void Connect(MyMQTTConnection con){
        String url;
        if(con.host.startsWith("tcp://"))
        {
            url = con.host + ":" + con.port;
        }else{
            url = "tcp://" + con.host + ":" + con.port;
        }
        mqttAndroidClient = new MqttAndroidClient(parent, url, con.client_id);

        MqttConnectOptions connectOptions = new MqttConnectOptions();
        connectOptions.setUserName(con.username);
        connectOptions.setPassword(con.password.toCharArray());
        connectOptions.setKeepAliveInterval(con.keep_alive);
        connectOptions.setCleanSession(con.clean_seasion);
        if(con.last_will_topic.length() != 0)
            connectOptions.setWill(con.last_will_topic, con.last_will_message.getBytes(), con.last_will_qos, con.last_will_retained);
        try {
            mqttAndroidClient.setCallback(mqttCallback);
            mqttAndroidClient.connect(connectOptions, null, connectCallback);
        }catch (Exception e){
            e.printStackTrace();
            Toast.makeText(parent, e.getMessage(), Toast.LENGTH_SHORT).show();
        }
    }

    IMqttActionListener connectCallback = new IMqttActionListener(){

        @Override
        public void onSuccess(IMqttToken iMqttToken) {
            status_label.setText("状态：已连接");
            Toast.makeText(parent, "连接成功", Toast.LENGTH_SHORT).show();
            new Thread(new Runnable() {
                @Override
                public void run() {
                    for(SubscribeTopic s : subscribeTopics){
                        try {
                            mqttAndroidClient.subscribe(s.topic, s.qos);
                            Thread.sleep(100);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }
            }).start();
        }
        @Override
        public void onFailure(IMqttToken iMqttToken, Throwable throwable) {
            Toast.makeText(parent, "连接失败", Toast.LENGTH_SHORT).show();
        }
    };

    MqttCallback mqttCallback = new MqttCallback() {
        @Override
        public void connectionLost(Throwable throwable) {
            status_label.setText("状态：未连接");
        }

        @Override
        public void messageArrived(String s, MqttMessage mqttMessage) throws Exception {
            MyMqttMessage mmsg = new MyMqttMessage(s, mqttMessage.getQos(), mqttMessage.isRetained(), new String(mqttMessage.getPayload()));
            myMqttMessages.add(mmsg);
            messageAdapter.notifyDataSetChanged();
            message_list.setSelection(myMqttMessages.size()-1);
        }

        @Override
        public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {

        }
    };

    public void Close(){

    }

}
